package com.meilingcloud.activiti.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.meilingcloud.activiti.domain.ActWfStock;
import com.meilingcloud.activiti.domain.dto.ActWfStockSaveDto;
import com.meilingcloud.activiti.domain.vo.ActStockDetailVo;
import com.meilingcloud.activiti.mapper.ActWfStockMapper;
import com.meilingcloud.activiti.service.IActWfStockService;
import com.meilingcloud.biobank.domain.*;
import com.meilingcloud.biobank.service.*;
import com.meilingcloud.common.config.BimsConfig;
import com.meilingcloud.common.constant.Constants;
import com.meilingcloud.common.core.domain.entity.SysUser;
import com.meilingcloud.common.enums.*;
import com.meilingcloud.common.exception.CustomException;
import com.meilingcloud.common.utils.SecurityUtils;
import com.meilingcloud.system.domain.SysAttach;
import com.meilingcloud.system.service.ISysAttachService;
import com.meilingcloud.system.service.ISysConfigService;
import com.meilingcloud.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 出入库单据 Service业务层处理
 *
 * @author chenl
 * @date 2021-03-15
 */
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Service
public class ActWfStockServiceImpl extends ServiceImpl<ActWfStockMapper, ActWfStock> implements IActWfStockService {

    private static final String KEEP_LOCATION_STATUS = "1"; // 领出时保持位置

    private final ProcessRuntime processRuntime;
    private final ISysUserService sysUserService;
    private final TaskService taskService;
    private final RuntimeService runtimeService;
    private final ISysConfigService sysConfigService;
    private final IStockSamplesService stockSamplesService;
    private final ISysAttachService sysAttachService;
    private final ISampleBackupService sampleBackupService;
    private final ITubeService tubeService;
    private final IContainerService containerService;
    private final ITubeHistoryService tubeHistoryService;
    private final ISampleTrashService sampleTrashService;
    private final SimpMessagingTemplate simpMessagingTemplate;

    @Override
    public List<ActWfStock> queryList(ActWfStock actWfStock) {
        LambdaQueryWrapper<ActWfStock> lqw = Wrappers.lambdaQuery();
        if (StringUtils.isNotBlank(actWfStock.getStockType())) {
            lqw.eq(ActWfStock::getStockType, actWfStock.getStockType());
        }
        if (StringUtils.isNotBlank(actWfStock.getStockTitle())) {
            lqw.eq(ActWfStock::getStockTitle, actWfStock.getStockTitle());
        }
        if (StringUtils.isNotBlank(actWfStock.getStockState())) {
            lqw.eq(ActWfStock::getStockState, actWfStock.getStockState());
        }
        if (StringUtils.isNotBlank(actWfStock.getCreateBy())) {
            lqw.eq(ActWfStock::getCreateBy, actWfStock.getCreateBy());
        }
        return this.list(lqw);
    }

    @Override
    public List<ActWfStock> queryStockWithTaskList(ActWfStock actWfStock) {
        List<ActWfStock> actWfStocks = this.queryList(actWfStock);
        List<String> instanceIds = actWfStocks.stream().map(ActWfStock::getInstanceId).collect(Collectors.toList());
        if (ObjectUtil.isNotEmpty(instanceIds)) {
            List<Task> tasks = taskService.createTaskQuery().processInstanceIdIn(instanceIds).list();
            actWfStocks.forEach(item -> {
                Task task = tasks.stream().filter(t -> t.getProcessInstanceId().equals(item.getInstanceId())).findAny().orElse(null);
                if (ObjectUtil.isNotNull(task)) {
                    item.setTaskName(task.getName());
                }
            });
        }
        return actWfStocks;
    }

    @Override
    public List<ActWfStock> queryStockInDeptList(ActWfStock actWfStock, List<String> userNames) {
        if (CollectionUtil.isEmpty(userNames)) {
            return null;
        }

        LambdaQueryWrapper<ActWfStock> lqw = Wrappers.lambdaQuery();
        if (StringUtils.isNotBlank(actWfStock.getStockType())) {
            lqw.eq(ActWfStock::getStockType, actWfStock.getStockType());
        }
        if (StringUtils.isNotBlank(actWfStock.getStockTitle())) {
            lqw.eq(ActWfStock::getStockTitle, actWfStock.getStockTitle());
        }
        if (StringUtils.isNotBlank(actWfStock.getStockState())) {
            lqw.eq(ActWfStock::getStockState, actWfStock.getStockState());
        }
        lqw.in(ActWfStock::getCreateBy, userNames);
        return this.list(lqw);
    }

    @Override
    public List<String> queryUserByDept() {
        SysUser sysUser = new SysUser();
        sysUser.setDeptId(SecurityUtils.getLoginUser().getUser().getDeptId());
        List<SysUser> sysUsers = sysUserService.selectUserList(sysUser);
        List<String> userNames = sysUsers.stream().map(SysUser::getUserName).collect(Collectors.toList());
        return userNames;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean revoke(String businessKey) {
        org.activiti.engine.runtime.ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceBusinessKey(businessKey).includeProcessVariables().singleResult();
        if (ObjectUtil.isEmpty(processInstance)) {
            throw new CustomException("此流程已结束");
        }
        runtimeService.deleteProcessInstance(processInstance.getId(), "用户撤销");
        // 删除流程历史信息
//        historyService.deleteHistoricProcessInstance(processInstance.getId());
        // 更改业务表状态为撤销
        ActWfStock actWfStock = this.getById(businessKey);
        actWfStock.setStockState(StockStatus.REVOKE.getCode());
        this.updateById(actWfStock);
        // 更改样本复份流程状态
        List<StockSamples> stockSamples = stockSamplesService.list(new LambdaQueryWrapper<StockSamples>()
                .eq(StockSamples::getStockId, businessKey));
        List<Long> sampBackupIds = stockSamples.stream().map(StockSamples::getSampBackupId).collect(Collectors.toList());
        List<SampleBackup> sampleBackups = sampleBackupService.listByIds(sampBackupIds);
        List<SampleBackup> sampleBackupList = sampleBackups.stream().map(item -> {
            item.setStockState(StockState.NORMAL.getCode());
            return item;
        }).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(sampleBackupList)) {
            return sampleBackupService.updateBatchById(sampleBackupList);
        }
        return false;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveWfStock(ActWfStockSaveDto actWfStockSaveDto) {
        List<SampleBackup> sampleBackups = actWfStockSaveDto.getSampleBackups();
        long count = sampleBackups.stream()
                .filter(item -> StringUtils.equals(item.getStockState(), StockState.PROCESS.getCode()))
                .count();
        if (count > 0) {
            throw new CustomException("当前选择的样本中含有其他进行中的流程所包含的样本，请刷新页面后重新选择");
        }
        ActWfStock actWfStock = new ActWfStock();
        BeanUtils.copyProperties(actWfStockSaveDto, actWfStock);
        String id = UUID.randomUUID().toString();
        actWfStock.setStockId(id);
        // 是否启用审批
        String activitiEnable = sysConfigService.selectConfigByKey("activiti.enable");
        boolean result = false;
        if (!StringUtils.equals(activitiEnable, Constants.ACTIVITI_ENABLE)) {
            result = saveStockByActivitiEnable("", actWfStock, sampleBackups, actWfStockSaveDto);
        }

        // 候选用户配置 ${deptLeader} or 候选组配置 se
        String deptLeaders = StringUtils.join(sysUserService.selectUserNameByPostCodeAndDeptId(BimsConfig.getPostCode(),
                SecurityUtils.getLoginUser().getUser().getDeptId()), ",");
        Map<String, Object> variableMap = new HashMap<>();
        variableMap.put("enable", activitiEnable);
        variableMap.put("deptLeader", deptLeaders);
        // 启动实例
        ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
                .start()
                .withProcessDefinitionKey("stock")
                .withName(actWfStock.getStockTitle())
                .withBusinessKey(id)
                .withVariables(variableMap)
                .build());
        // WebSocket通知
        List<String> deptLeaderList = Arrays.asList(deptLeaders.split(","));
        if (CollectionUtil.isNotEmpty(deptLeaderList)) {
            deptLeaderList.forEach(item -> {
                simpMessagingTemplate.convertAndSendToUser(item, "/topic/activiti", "您收到 " + actWfStockSaveDto.getStockTitle());
            });
        }
        if (StringUtils.equals(activitiEnable, Constants.ACTIVITI_ENABLE)) {
            result = saveStockByActivitiEnable(processInstance.getId(), actWfStock, sampleBackups, actWfStockSaveDto);
        }

        return result;
    }

    // 根据是否需要activiti审批设置 保存业务数据时间节点不同
    @Transactional(rollbackFor = Exception.class)
    public boolean saveStockByActivitiEnable(String processInstanceId, ActWfStock actWfStock,
                                             List<SampleBackup> sampleBackups, ActWfStockSaveDto actWfStockSaveDto) {
        if (StringUtils.isNotBlank(processInstanceId)) {
            actWfStock.setInstanceId(processInstanceId);
        }
        // 业务表写入数据
        actWfStock.setStockState(StockStatus.UNDERWAY.getCode());
        actWfStock.setCreateName(SecurityUtils.getNickName());
        actWfStock.setCreateBy(SecurityUtils.getUsername());
        boolean result = this.save(actWfStock);
        // 更新样本库存状态为流程状态
        List<SampleBackup> sampleBackupList = sampleBackups.stream().map(item -> {
            item.setStockState(StockState.PROCESS.getCode());
            return item;
        }).collect(Collectors.toList());
        sampleBackupService.updateBatchById(sampleBackupList);
        // 写入stock_samp关联表
        if (CollectionUtil.isNotEmpty(sampleBackups)) {
            List<StockSamples> stockSamplesList = new ArrayList<>();
            sampleBackups.forEach(item -> {
                StockSamples stockSamples = new StockSamples();
                BeanUtils.copyProperties(item, stockSamples);
                stockSamples.setStockId(actWfStock.getStockId());
                stockSamplesList.add(stockSamples);
            });

            stockSamplesService.saveBatch(stockSamplesList);
        }
        // 写入附件表
        List<SysAttach> attaches = actWfStockSaveDto.getAttaches();
        if (CollectionUtil.isNotEmpty(attaches)) {
            List<SysAttach> attachList = attaches.stream().map(item -> {
                item.setRelateId(actWfStock.getStockId());
                item.setModule(AttachModule.WF_STOCK.getCode());
                item.setCreateBy(SecurityUtils.getUsername());
                return item;
            }).collect(Collectors.toList());
            sysAttachService.saveBatch(attachList);
        }
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean completeStock(ActWfStock wfStock) {
        ActWfStock actWfStock = this.getById(wfStock.getStockId());
        actWfStock.setStockState(wfStock.getStockState());
        actWfStock.setInstanceId(wfStock.getInstanceId());
        List<StockSamples> stockSamples = stockSamplesService.list(new LambdaQueryWrapper<StockSamples>()
                .eq(StockSamples::getStockId, actWfStock.getStockId()));
        List<Long> sampBackupIds = stockSamples.stream().map(StockSamples::getSampBackupId).collect(Collectors.toList());
        boolean wfSuccess = StockStatus.SUCCESS.getCode().equals(actWfStock.getStockState()) ||
                StockStatus.AUTO.getCode().equals(actWfStock.getStockState());
        boolean wfFail = StockStatus.FAIL.getCode().equals(actWfStock.getStockState());
        StockType stockType = StockType.getTypeByCode(actWfStock.getStockType());
        List<TubeHistory> tubeHistoryList = new ArrayList<>();
        switch (stockType) {
            case IN:  // 入库
                if (wfSuccess) {
                    // 入库流程完成
                    // 更改tube表和sampleBackup表状态
                    List<SampleBackup> sampleBackups = sampleBackupService.listByIds(sampBackupIds);
                    List<SampleBackup> sampleBackupList = sampleBackups.stream().map(item -> {
                        item.setSampState(SampStatue.NORMAL.getCode()); // 样本状态 正常
                        item.setStockState(StockState.NORMAL.getCode());
                        return item;
                    }).collect(Collectors.toList());
                    sampleBackupService.updateBatchById(sampleBackupList);

                    Map<Long, Integer> map = new HashMap<>();
                    List<Tube> tubes = tubeService.list(new LambdaQueryWrapper<Tube>().in(Tube::getSampBackupId, sampBackupIds));
                    List<Tube> tubeList = tubes.stream().map(item -> {
                        if (map.containsKey(item.getContainerId())) {
                            map.put(item.getContainerId(), map.get(item.getContainerId()) + 1);
                        } else {
                            map.put(item.getContainerId(), 1);
                        }
                        item.setTubeState(TubeStatus.NORMAL.getCode());
                        // 历史记录
                        TubeHistory tubeHistory = new TubeHistory();
                        tubeHistory.setTubeId(item.getTubeId());
                        tubeHistory.setOperator(actWfStock.getCreateBy());
                        tubeHistory.setOperatorType(actWfStock.getStockType());
                        tubeHistory.setOperatorTime(actWfStock.getCreateTime());
                        tubeHistory.setOperateContent(Objects.requireNonNull(sampleBackups.stream()
                                .filter(s -> ObjectUtil.equal(s.getSampBackupId(), item.getSampBackupId()))
                                .findFirst().orElse(null)).getSampBackupCode());
                        tubeHistoryList.add(tubeHistory);
                        return item;
                    }).collect(Collectors.toList());
                    tubeService.updateBatchById(tubeList);
                    // 增加容器表当前存储数量
                    Set<Long> containerIdSet = map.keySet();
                    Iterator<Long> it = containerIdSet.iterator();
                    while (it.hasNext()) {
                        Long containerId = it.next();
                        Integer count = map.get(containerId);
                        List<Container> containers = containerService.getAllParentsByChild(containerId);
                        List<Container> containerList = containers.stream().map(item -> {
                            item.setCurrentCount(item.getCurrentCount() + count); // 增加数量
                            return item;
                        }).collect(Collectors.toList());
                        containerService.updateContainerBatch(containerList);
                    }
                    // 写历史记录表
                    tubeHistoryService.saveBatch(tubeHistoryList);
                } else if (wfFail) {
                    // 入库流程失败
                    // tube表清空sampBackupId、修改状态 sampleBackup表状态
                    List<SampleBackup> sampleBackups = sampleBackupService.listByIds(sampBackupIds);
                    List<SampleBackup> sampleBackupList = sampleBackups.stream().map(item -> {
                        item.setSampState(SampStatue.VIRTUAL.getCode());
                        item.setStockState(StockState.NORMAL.getCode());
                        item.setSampLocation("");
                        return item;
                    }).collect(Collectors.toList());
                    sampleBackupService.updateBatchById(sampleBackupList);
                    List<Tube> tubes = tubeService.list(new LambdaQueryWrapper<Tube>().in(Tube::getSampBackupId, sampBackupIds));
                    List<Tube> tubeList = tubes.stream().map(item -> {
                        item.setTubeState(TubeStatus.NORMAL.getCode());
                        item.setSampBackupId(0L);
                        return item;
                    }).collect(Collectors.toList());
                    tubeService.updateBatchById(tubeList);
                }
                break;
            case OUT: // 出库
                if (wfSuccess) {
                    // 出库流程完成 更改样本状态、冻融次数加1、清除样本位置 清空冻存管表sampBackupId
                    List<SampleBackup> sampleBackups = sampleBackupService.listByIds(sampBackupIds);
                    List<SampleBackup> sampleBackupList = sampleBackups.stream().map(item -> {
                        item.setSampState(SampStatue.OUT.getCode()); // 样本状态 出库
                        item.setStockState(StockState.NORMAL.getCode());
                        item.setSampFreezeThawCount(item.getSampFreezeThawCount() + 1);
                        item.setSampLocation("");
                        return item;
                    }).collect(Collectors.toList());
                    sampleBackupService.updateBatchById(sampleBackupList);

                    Map<Long, Integer> map = new HashMap<>();
                    List<Tube> tubes = tubeService.list(new LambdaQueryWrapper<Tube>().in(Tube::getSampBackupId, sampBackupIds));
                    List<Tube> tubeList = tubes.stream().map(item -> {
                        if (map.containsKey(item.getContainerId())) {
                            map.put(item.getContainerId(), map.get(item.getContainerId()) + 1);
                        } else {
                            map.put(item.getContainerId(), 1);
                        }
                        // 历史记录
                        TubeHistory tubeHistory = new TubeHistory();
                        tubeHistory.setTubeId(item.getTubeId());
                        tubeHistory.setOperator(actWfStock.getCreateBy());
                        tubeHistory.setOperatorType(actWfStock.getStockType());
                        tubeHistory.setOperatorTime(actWfStock.getCreateTime());
                        tubeHistory.setOperateContent(Objects.requireNonNull(sampleBackups.stream()
                                .filter(s -> ObjectUtil.equal(s.getSampBackupId(), item.getSampBackupId()))
                                .findFirst().orElse(null)).getSampBackupCode());
                        tubeHistoryList.add(tubeHistory);
                        item.setSampBackupId(0L);
                        return item;
                    }).collect(Collectors.toList());
                    tubeService.updateBatchById(tubeList);

                    // 更新容器表当前存储数量
                    Set<Long> containerIdSet = map.keySet();
                    Iterator<Long> it = containerIdSet.iterator();
                    while (it.hasNext()) {
                        Long containerId = it.next();
                        Integer count = map.get(containerId);
                        List<Container> containers = containerService.getAllParentsByChild(containerId);
                        List<Container> containerList = containers.stream().map(item -> {
                            item.setCurrentCount(item.getCurrentCount() - count); // 减少数量
                            return item;
                        }).collect(Collectors.toList());
                        containerService.updateContainerBatch(containerList);
                    }
                    // 写历史记录表
                    tubeHistoryService.saveBatch(tubeHistoryList);
                } else if (wfFail) {
                    // 出库流程失败
                    List<SampleBackup> sampleBackups = sampleBackupService.listByIds(sampBackupIds);
                    List<SampleBackup> sampleBackupList = sampleBackups.stream().map(item -> {
                        item.setStockState(StockState.NORMAL.getCode());
                        return item;
                    }).collect(Collectors.toList());
                    sampleBackupService.updateBatchById(sampleBackupList);
                }
                break;
            case CLAIM:   // 申领
                if (wfSuccess) {
                    // 申领完成 更改样本状态、冻融次数加1 保留位置->更改冻存管占用状态 不保留位置->清除样本位置及冻存管表sampBackupId
                    boolean keepLocation = KEEP_LOCATION_STATUS.equals(actWfStock.getKeepLocation());
                    List<SampleBackup> sampleBackups = sampleBackupService.listByIds(sampBackupIds);
                    List<SampleBackup> sampleBackupList = sampleBackups.stream().map(item -> {
                        item.setSampState(SampStatue.CLAIM.getCode()); // 样本状态 领出
                        item.setStockState(StockState.NORMAL.getCode());
                        item.setSampFreezeThawCount(item.getSampFreezeThawCount() + 1);
                        if (!keepLocation) {
                            item.setSampLocation("");
                        }
                        return item;
                    }).collect(Collectors.toList());
                    sampleBackupService.updateBatchById(sampleBackupList);

                    Map<Long, Integer> map = new HashMap<>();
                    List<Tube> tubes = tubeService.list(new LambdaQueryWrapper<Tube>().in(Tube::getSampBackupId, sampBackupIds));
                    List<Tube> tubeList = tubes.stream().map(item -> {
                        if (map.containsKey(item.getContainerId())) {
                            map.put(item.getContainerId(), map.get(item.getContainerId()) + 1);
                        } else {
                            map.put(item.getContainerId(), 1);
                        }
                        // 历史记录
                        TubeHistory tubeHistory = new TubeHistory();
                        tubeHistory.setTubeId(item.getTubeId());
                        tubeHistory.setOperator(actWfStock.getCreateBy());
                        tubeHistory.setOperatorType(actWfStock.getStockType());
                        tubeHistory.setOperatorTime(actWfStock.getCreateTime());
                        tubeHistory.setOperateContent(Objects.requireNonNull(sampleBackups.stream()
                                .filter(s -> ObjectUtil.equal(s.getSampBackupId(), item.getSampBackupId()))
                                .findFirst().orElse(null)).getSampBackupCode());
                        tubeHistoryList.add(tubeHistory);
                        if (keepLocation) {
                            item.setTubeState(TubeStatus.OCCUPY.getCode()); // 占用状态
                        } else {
                            item.setSampBackupId(0L);
                        }
                        return item;
                    }).collect(Collectors.toList());
                    tubeService.updateBatchById(tubeList);

                    // 更新容器表当前存储数量
                    Set<Long> containerIdSet = map.keySet();
                    Iterator<Long> it = containerIdSet.iterator();
                    while (it.hasNext()) {
                        Long containerId = it.next();
                        Integer count = map.get(containerId);
                        List<Container> containers = containerService.getAllParentsByChild(containerId);
                        List<Container> containerList = containers.stream().map(item -> {
                            item.setCurrentCount(item.getCurrentCount() - count); // 减少数量
                            return item;
                        }).collect(Collectors.toList());
                        containerService.updateContainerBatch(containerList);
                    }
                    // 写历史记录表
                    tubeHistoryService.saveBatch(tubeHistoryList);
                } else if (wfFail) {
                    // 失败
                    List<SampleBackup> sampleBackups = sampleBackupService.listByIds(sampBackupIds);
                    List<SampleBackup> sampleBackupList = sampleBackups.stream().map(item -> {
                        item.setStockState(StockState.NORMAL.getCode());
                        return item;
                    }).collect(Collectors.toList());
                    sampleBackupService.updateBatchById(sampleBackupList);
                }
                break;
            case RETURN:  // 归还
                if (wfSuccess) {
                    // 归还完成 更改样本状态 冻存管状态无论是否正常,全部更新为正常
                    List<SampleBackup> sampleBackups = sampleBackupService.listByIds(sampBackupIds);
                    List<SampleBackup> sampleBackupList = sampleBackups.stream().map(item -> {
                        item.setSampState(SampStatue.NORMAL.getCode()); // 样本状态 正常
                        item.setStockState(StockState.NORMAL.getCode());
                        return item;
                    }).collect(Collectors.toList());
                    sampleBackupService.updateBatchById(sampleBackupList);

                    Map<Long, Integer> map = new HashMap<>();
                    List<Tube> tubes = tubeService.list(new LambdaQueryWrapper<Tube>().in(Tube::getSampBackupId, sampBackupIds));
                    List<Tube> tubeList = tubes.stream().map(item -> {
                        if (map.containsKey(item.getContainerId())) {
                            map.put(item.getContainerId(), map.get(item.getContainerId()) + 1);
                        } else {
                            map.put(item.getContainerId(), 1);
                        }
                        item.setTubeState(TubeStatus.NORMAL.getCode());
                        // 历史记录
                        TubeHistory tubeHistory = new TubeHistory();
                        tubeHistory.setOperator(actWfStock.getCreateBy());
                        tubeHistory.setOperatorType(actWfStock.getStockType());
                        tubeHistory.setOperatorTime(actWfStock.getCreateTime());
                        tubeHistory.setOperatorType(stockType.getCode());
                        tubeHistory.setOperateContent(Objects.requireNonNull(sampleBackups.stream()
                                .filter(s -> ObjectUtil.equal(s.getSampBackupId(), item.getSampBackupId()))
                                .findFirst().orElse(null)).getSampBackupCode());
                        tubeHistoryList.add(tubeHistory);
                        return item;
                    }).collect(Collectors.toList());
                    tubeService.updateBatchById(tubeList);
                    // 增加容器表当前存储数量
                    Set<Long> containerIdSet = map.keySet();
                    Iterator<Long> it = containerIdSet.iterator();
                    while (it.hasNext()) {
                        Long containerId = it.next();
                        Integer count = map.get(containerId);
                        List<Container> containers = containerService.getAllParentsByChild(containerId);
                        List<Container> containerList = containers.stream().map(item -> {
                            item.setCurrentCount(item.getCurrentCount() + count); // 增加数量
                            return item;
                        }).collect(Collectors.toList());
                        containerService.updateContainerBatch(containerList);
                    }
                    // 写历史记录表
                    tubeHistoryService.saveBatch(tubeHistoryList);
                } else if (wfFail) {
                    // 失败
                    List<SampleBackup> sampleBackups = sampleBackupService.listByIds(sampBackupIds);
                    List<SampleBackup> sampleBackupList = sampleBackups.stream().map(item -> {
                        item.setStockState(StockState.NORMAL.getCode());
                        return item;
                    }).collect(Collectors.toList());
                    sampleBackupService.updateBatchById(sampleBackupList);
                }
                break;
            case DESTROY: // 销毁
                if (wfSuccess) {
                    // 销毁流程完成 清空样本位置、更改样本状态为销毁 写入回收站表 清空冻存管表sampBackupId
                    List<SampleTrash> sampleTrashList = new ArrayList<>();
                    List<SampleBackup> sampleBackups = sampleBackupService.listByIds(sampBackupIds);
                    List<SampleBackup> sampleBackupList = sampleBackups.stream().map(item -> {
                        item.setSampLocation("");
                        item.setSampState(SampStatue.DESTROY.getCode());
                        SampleTrash sampleTrash = new SampleTrash();
                        sampleTrash.setSampBackupId(item.getSampBackupId());
                        sampleTrash.setSampBackupCode(item.getSampBackupCode());
                        sampleTrash.setSampTypeId(item.getSampTypeId());
                        sampleTrash.setRemark(actWfStock.getStockDesc());
                        sampleTrash.setCreateBy(actWfStock.getCreateBy());
                        sampleTrashList.add(sampleTrash);
                        return item;
                    }).collect(Collectors.toList());
                    sampleBackupService.updateBatchById(sampleBackupList);
//                    sampleBackupService.removeByIds(sampBackupIds);// 销毁时只改状态不删除

                    Map<Long, Integer> map = new HashMap<>();
                    List<Tube> tubes = tubeService.list(new LambdaQueryWrapper<Tube>().in(Tube::getSampBackupId, sampBackupIds));
                    List<Tube> tubeList = tubes.stream().map(item -> {
                        if (map.containsKey(item.getContainerId())) {
                            map.put(item.getContainerId(), map.get(item.getContainerId()) + 1);
                        } else {
                            map.put(item.getContainerId(), 1);
                        }
                        // 历史记录
                        TubeHistory tubeHistory = new TubeHistory();
                        tubeHistory.setTubeId(item.getTubeId());
                        tubeHistory.setOperator(actWfStock.getCreateBy());
                        tubeHistory.setOperatorType(actWfStock.getStockType());
                        tubeHistory.setOperatorTime(actWfStock.getCreateTime());
                        tubeHistory.setOperateContent(Objects.requireNonNull(sampleBackups.stream()
                                .filter(s -> ObjectUtil.equal(s.getSampBackupId(), item.getSampBackupId()))
                                .findFirst().orElse(null)).getSampBackupCode());
                        tubeHistoryList.add(tubeHistory);
                        item.setSampBackupId(0L);
                        return item;
                    }).collect(Collectors.toList());
                    tubeService.updateBatchById(tubeList);

                    // 更新容器表当前存储数量
                    Set<Long> containerIdSet = map.keySet();
                    Iterator<Long> it = containerIdSet.iterator();
                    while (it.hasNext()) {
                        Long containerId = it.next();
                        Integer count = map.get(containerId);
                        List<Container> containers = containerService.getAllParentsByChild(containerId);
                        List<Container> containerList = containers.stream().map(item -> {
                            item.setCurrentCount(item.getCurrentCount() - count); // 减少数量
                            return item;
                        }).collect(Collectors.toList());
                        containerService.updateContainerBatch(containerList);
                    }
                    // 写历史记录表
                    tubeHistoryService.saveBatch(tubeHistoryList);
                    // 写回收站表
                    sampleTrashService.saveBatch(sampleTrashList);
                } else if (wfFail) {
                    // 失败 do nothing
                }
                break;
            default:
                break;
        }
        return this.updateById(actWfStock);
    }

    @Override
    public ActStockDetailVo getStockDetail(String stockId) {
        ActWfStock actWfStock = this.getById(stockId);
        if (ObjectUtil.isEmpty(actWfStock)) {
            return null;
        }
        ActStockDetailVo actStockDetailVo = new ActStockDetailVo();
        BeanUtils.copyProperties(actWfStock, actStockDetailVo);
        List<StockSamples> stockSamplesList = stockSamplesService.getStockSamplesByOrder(stockId);
        actStockDetailVo.setSampleBackups(stockSamplesList);

        SysAttach sysAttach = new SysAttach();
        sysAttach.setRelateId(stockId);
        sysAttach.setModule(AttachModule.WF_STOCK.getCode());
        List<SysAttach> sysAttaches = sysAttachService.queryList(sysAttach);
        actStockDetailVo.setAttaches(sysAttaches);
        return actStockDetailVo;
    }
}
